package org.jxf.gps.jt808.server;




import org.apache.log4j.Logger;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ChildChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.WriteCompletionEvent;
import org.jxf.gps.jt808.message.MsgHandle;


@ChannelPipelineCoverage("all")
public class ServerHandler extends SimpleChannelHandler {
	
	private static Logger logger = Logger.getLogger(ServerHandler.class);

	@Override
	public void bindRequested(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		
		super.bindRequested(ctx, e);
		logger.debug(this + " "+"bindRequested");
	}

	@Override
	public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		
		super.channelBound(ctx, e);
		logger.debug(this + " "+"channelBound");
	}

	@Override
	public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		
		super.channelClosed(ctx, e);
		logger.debug(this + " "+"channelClosed");
	}

	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		
		super.channelConnected(ctx, e);
		synchronized(GpsServer.tcpConnCountLock){
			GpsServer.tcpConnCount++;
		}
		logger.debug(this + " "+"channelConnected remote = " + e.getChannel().getRemoteAddress());
	}

	@Override
	public void channelDisconnected(ChannelHandlerContext ctx,
			ChannelStateEvent e) throws Exception {
		
		super.channelDisconnected(ctx, e);
		synchronized(GpsServer.tcpConnCountLock){
			GpsServer.tcpConnCount--;
		}
		logger.debug(this + " "+"channelDisconnected");
	}

	@Override
	public void channelInterestChanged(ChannelHandlerContext ctx,
			ChannelStateEvent e) throws Exception {
		
		super.channelInterestChanged(ctx, e);
		logger.debug(this + " "+"channelInterestChanged");
	}

	@Override
	public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		
		super.channelOpen(ctx, e);
		Server.allChannels.add(e.getChannel());
		//Thread.sleep(3000);
		logger.debug(this + " "+"channelOpen remote = " + e.getChannel().getRemoteAddress() + " total="+Server.allChannels.size());
	}

	@Override
	public void channelUnbound(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		
		super.channelUnbound(ctx, e);
		logger.debug(this + " "+"channelUnbound");
	}

	@Override
	public void childChannelClosed(ChannelHandlerContext ctx,
			ChildChannelStateEvent e) throws Exception {
		
		super.childChannelClosed(ctx, e);
		logger.debug(this + " "+"childChannelClosed remote = " + e.getChannel().getRemoteAddress());
	}

	@Override
	public void childChannelOpen(ChannelHandlerContext ctx,
			ChildChannelStateEvent e) throws Exception {
		
		super.childChannelOpen(ctx, e);
		logger.debug(this + " "+"childChannelOpen");
	}

	@Override
	public void closeRequested(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		
		super.closeRequested(ctx, e);
		logger.debug(this + " "+"childChannelOpen");
	}

	@Override
	public void connectRequested(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		
		super.connectRequested(ctx, e);
		logger.debug(this + " "+"connectRequested");
	}

	@Override
	public void disconnectRequested(ChannelHandlerContext ctx,
			ChannelStateEvent e) throws Exception {
		
		super.disconnectRequested(ctx, e);
		logger.debug(this + " "+"disconnectRequested");
	}

	@Override
	public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e)
			throws Exception {
		
		super.handleDownstream(ctx, e);
		logger.debug(this + " "+"handleDownstream");
	}

	@Override
	public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
			throws Exception {
		
		super.handleUpstream(ctx, e);
		logger.debug(this + " "+"handleUpstream");
	}

	@Override
	public void setInterestOpsRequested(ChannelHandlerContext ctx,
			ChannelStateEvent e) throws Exception {
		
		super.setInterestOpsRequested(ctx, e);
		logger.debug(this + " "+"setInterestOpsRequested");
	}

	@Override
	public void unbindRequested(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		
		super.unbindRequested(ctx, e);
		logger.debug(this + " "+"unbindRequested");
	}

	@Override
	public void writeComplete(ChannelHandlerContext ctx, WriteCompletionEvent e)
			throws Exception {
		
		super.writeComplete(ctx, e);
		logger.debug(this + " "+"writeComplete");
	}

	@Override
	public void writeRequested(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		
		super.writeRequested(ctx, e);
		logger.debug(this + " "+"writeRequested");
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
			throws Exception {
		
		super.exceptionCaught(ctx, e);
		//是否应不因为处理中的异常，关闭连接？
		Channel ch = e.getChannel();
		ch.close();
		logger.error(this + " "+"exceptionCaught",e.getCause());
		GpsServer.tcpExceptionCaught++;
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		
		super.messageReceived(ctx, e);
		long t1 = System.currentTimeMillis();
		
		synchronized(GpsServer.tcpMsgRecvCountLock){
			GpsServer.tcpMsgRecvCount++;
			GpsServer.tcpMsgQCount++;
		}
		try{
			MsgHandle handle = new MsgHandle(e);
			handle.handle();
		}catch(Exception ex){
			ex.printStackTrace();
			logger.error(this + " "+"messageReceived",ex.getCause());
			GpsServer.tcpMsgRevErrCount++;
		}
		long t2 = System.currentTimeMillis();
		synchronized(GpsServer.tcpMsgRecvCountLock){
			GpsServer.tcpMsgQCount--;
		}
		//logger.info("MsgHandle consume : "+(t2 - t1));
	}

}
